from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import json


class JenkinsServer(models.Model):
    """Jenkins服务器配置"""
    name = models.CharField(max_length=100, verbose_name='服务器名称')
    url = models.URLField(verbose_name='Jenkins URL')
    username = models.CharField(max_length=100, verbose_name='用户名')
    api_token = models.CharField(max_length=255, verbose_name='API Token')
    description = models.TextField(blank=True, null=True, verbose_name='描述')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')

    # 连接状态
    status = models.CharField(
        max_length=20,
        choices=[
            ('connected', '已连接'),
            ('disconnected', '连接失败'),
            ('error', '错误'),
            ('testing', '测试中'),
        ],
        default='disconnected',
        verbose_name='连接状态'
    )

    # 统计信息
    job_count = models.IntegerField(default=0, verbose_name='任务数量')
    last_sync = models.DateTimeField(null=True, blank=True, verbose_name='最后同步时间')
    last_check = models.DateTimeField(null=True, blank=True, verbose_name='最后检查时间')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = 'Jenkins服务器'
        verbose_name_plural = 'Jenkins服务器'
        unique_together = ['url']

    def __str__(self):
        return self.name


class Project(models.Model):
    """项目模型 - 复用GitLab的项目模型"""
    name = models.CharField(max_length=100, verbose_name='项目名称')
    code = models.CharField(max_length=50, unique=True, verbose_name='项目代码')
    description = models.TextField(blank=True, null=True, verbose_name='项目描述')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '项目'
        verbose_name_plural = '项目'

    def __str__(self):
        return self.name


class Environment(models.Model):
    """环境模型 - 复用GitLab的环境模型"""
    name = models.CharField(max_length=50, verbose_name='环境名称')
    code = models.CharField(max_length=20, unique=True, verbose_name='环境代码')
    description = models.TextField(blank=True, null=True, verbose_name='环境描述')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '环境'
        verbose_name_plural = '环境'

    def __str__(self):
        return self.name


class JenkinsJob(models.Model):
    """Jenkins任务"""
    JOB_TYPES = [
        ('freestyle', 'Freestyle项目'),
        ('maven', 'Maven项目'),
        ('pipeline', 'Pipeline'),
    ]

    name = models.CharField(max_length=200, verbose_name='任务名称')
    description = models.TextField(blank=True, null=True, verbose_name='任务描述')
    job_type = models.CharField(max_length=20, choices=JOB_TYPES, verbose_name='任务类型')

    # 关联关系
    project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='所属项目')
    environment = models.ForeignKey(Environment, on_delete=models.CASCADE, verbose_name='所属环境')
    jenkins_server = models.ForeignKey(JenkinsServer, on_delete=models.CASCADE, verbose_name='Jenkins服务器')

    # Jenkins相关信息
    jenkins_job_name = models.CharField(max_length=200, verbose_name='Jenkins中的任务名称')
    jenkins_job_url = models.URLField(blank=True, null=True, verbose_name='Jenkins任务URL')

    # GitLab关联
    gitlab_project_id = models.IntegerField(null=True, blank=True, verbose_name='关联的GitLab项目ID')
    gitlab_project_name = models.CharField(max_length=200, blank=True, null=True, verbose_name='GitLab项目名称')

    # 构建状态
    last_build_number = models.IntegerField(null=True, blank=True, verbose_name='最后构建号')
    last_build_status = models.CharField(
        max_length=20,
        choices=[
            ('SUCCESS', '成功'),
            ('FAILURE', '失败'),
            ('UNSTABLE', '不稳定'),
            ('ABORTED', '已中止'),
            ('NOT_BUILT', '未构建'),
        ],
        null=True, blank=True,
        verbose_name='最后构建状态'
    )
    last_build_time = models.DateTimeField(null=True, blank=True, verbose_name='最后构建时间')

    # 配置信息
    config_xml = models.TextField(blank=True, null=True, verbose_name='Jenkins配置XML')
    config_json = models.JSONField(default=dict, blank=True, verbose_name='任务配置JSON')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = 'Jenkins任务'
        verbose_name_plural = 'Jenkins任务'
        unique_together = ['jenkins_server', 'jenkins_job_name']

    def __str__(self):
        return f"{self.project.name}-{self.environment.name}-{self.name}"


class JenkinsBuild(models.Model):
    """Jenkins构建记录"""
    job = models.ForeignKey(JenkinsJob, on_delete=models.CASCADE, verbose_name='关联任务')
    build_number = models.IntegerField(verbose_name='构建号')

    # 构建状态
    status = models.CharField(
        max_length=20,
        choices=[
            ('SUCCESS', '成功'),
            ('FAILURE', '失败'),
            ('UNSTABLE', '不稳定'),
            ('ABORTED', '已中止'),
            ('BUILDING', '构建中'),
        ],
        verbose_name='构建状态'
    )

    # 构建信息
    duration = models.IntegerField(null=True, blank=True, verbose_name='构建时长(毫秒)')
    start_time = models.DateTimeField(verbose_name='开始时间')
    end_time = models.DateTimeField(null=True, blank=True, verbose_name='结束时间')

    # 构建参数和结果
    parameters = models.JSONField(default=dict, blank=True, verbose_name='构建参数')
    console_output = models.TextField(blank=True, null=True, verbose_name='控制台输出')

    # 关联信息
    triggered_by = models.CharField(max_length=100, blank=True, null=True, verbose_name='触发者')
    git_commit = models.CharField(max_length=40, blank=True, null=True, verbose_name='Git提交ID')
    git_branch = models.CharField(max_length=100, blank=True, null=True, verbose_name='Git分支')

    # Jenkins URL
    jenkins_build_url = models.URLField(blank=True, null=True, verbose_name='Jenkins构建URL')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = 'Jenkins构建记录'
        verbose_name_plural = 'Jenkins构建记录'
        unique_together = ['job', 'build_number']
        ordering = ['-build_number']

    def __str__(self):
        return f"{self.job.name} #{self.build_number}"


class JenkinsAudit(models.Model):
    """Jenkins操作审计"""
    OPERATION_TYPES = [
        ('jenkins_server_create', 'Jenkins服务器创建'),
        ('jenkins_server_update', 'Jenkins服务器更新'),
        ('jenkins_server_delete', 'Jenkins服务器删除'),
        ('jenkins_server_test', 'Jenkins服务器连接测试'),
        ('jenkins_job_create', 'Jenkins任务创建'),
        ('jenkins_job_update', 'Jenkins任务更新'),
        ('jenkins_job_delete', 'Jenkins任务删除'),
        ('jenkins_job_sync', 'Jenkins任务同步'),
        ('jenkins_build_trigger', 'Jenkins构建触发'),
        ('jenkins_build_abort', 'Jenkins构建中止'),
    ]

    # 基本信息
    operation_type = models.CharField(max_length=50, choices=OPERATION_TYPES, verbose_name='操作类型')
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name='操作用户')

    # 关联对象
    project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='关联项目')
    environment = models.ForeignKey(Environment, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='关联环境')
    jenkins_server = models.ForeignKey(JenkinsServer, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='Jenkins服务器')
    jenkins_job = models.ForeignKey(JenkinsJob, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='Jenkins任务')

    # 操作结果
    result = models.CharField(
        max_length=20,
        choices=[
            ('success', '成功'),
            ('failed', '失败'),
        ],
        verbose_name='操作结果'
    )

    # 详细信息
    details = models.JSONField(default=dict, blank=True, verbose_name='操作详情')
    error_message = models.TextField(blank=True, null=True, verbose_name='错误信息')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='操作时间')

    class Meta:
        verbose_name = 'Jenkins操作审计'
        verbose_name_plural = 'Jenkins操作审计'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.get_operation_type_display()} - {self.user.username if self.user else 'System'}"
